#ifndef COMB_SNP_CALL_HPP__
#define COMB_SNP_CALL_HPP__

#include "util.hpp"
#include "priors.hpp"
#include "perm_parser.hpp"
#include "snp_cand.hpp"
#include "serialization.hpp"
#include "cartesian_product.hpp"

#include <iostream>

/** Given an array of probabilities for a block of adjacent SNP candidates find the best block to call, and generate pseudo-probabilities for all the bases as each position.
 * \param options options used to call comb
 * \param snp the snp to solve
 * \param M An array to populate with per site per base probabilities.
 */
int solve_col_snp(prog_options &options, ColorSnpCall &snp, std::vector<std::vector<double> > &M);

/** Pretty print the output of called color space snps.
 * \param options the options comb was called with.
 * \param snp_cands the snp calls that we want to report.
 */
void print_col_snps(prog_options &options, color_call_vector_t &snp_cands);

/** Pretty print the output of called sequence space snps.
 * \param options the options comb was called with.
 * \param snp_cands the snp calls that we want to report.
 */
void print_seq_snps(prog_options &options, seq_call_vector_t &snp_cands);

/** Using the reads, calculate the probabilities of each possibility for each snp block.
 * \param options the options comb was called with
 * \param cand_blocks the SNP candidates.
 * \param snp_cands the snp call data structure.
 * \param call_rates information for assesing read quality.
 * \param read_length the size of the reads.
 * \param qual_bins rebinning structure for qualities.
 */
void call_snps(prog_options &options, cand_blocks_t &cand_blocks, color_call_vector_t &snp_cands, array_type5 &call_rates, unsigned int read_length, boost::multi_array<int, 2> &qual_bins);

/** Driver for "comb snpcall" 
 */
void do_snpcall(int argc, char **argv);

/** Using the reads, calculate the probabilities of each possibility for each snp block.
 * \param options the options comb was called with
 * \param cand_blocks the SNP candidates.
 * \param snp_cands the snp call data structure.
 * \param call_rates information for assesing read quality.
 * \param read_length the size of the reads.
 * \param qual_bins rebinning structure for qualities.
 */
void call_seq_snps(prog_options &options, cand_blocks_t &cand_blocks, seq_call_vector_t &snp_cands, array_type4 &call_rates, unsigned int read_length, boost::multi_array<int, 2> &qual_bins);

/** Apply the priors to all the SNP candidates. */
void multiply_seq_snp_calls_by_priors(prog_options &options, seq_call_vector_t &snps);

/** Apply the priors to all the SNP candidates. */
void multiply_col_snp_calls_by_priors(prog_options &options, color_call_vector_t &snps);

#endif
